package com.william.jdbcplus.core.query;

import com.william.jdbcplus.common.entity.Entity;
import com.william.jdbcplus.core.condition.segment.MergeSegments;
import com.william.jdbcplus.core.condition.wrap.AbstractWrap;
import com.william.jdbcplus.core.enums.SqlKeyword;
import com.william.jdbcplus.core.meta.TableHelperUtil;
import com.william.jdbcplus.core.toolkit.SQLKeyUtils;
import com.william.jdbcplus.core.toolkit.StringPool;
import com.william.jdbcplus.core.toolkit.lambda.LambdaUtils;
import com.william.jdbcplus.core.toolkit.lambda.support.SFunction;

import java.util.Arrays;
import java.util.Map;

import static java.util.stream.Collectors.joining;

/**
 * Lambda 语法使用 Wrapper
 *
 * @author niliwei
 */
public class EntityLambdaWrap<T extends Entity> extends AbstractWrap<SFunction<T, ?>, EntityLambdaWrap<T>> {

    private Class<T> entityClass;

    /**
     * 查询条件
     */
    private EntityWrap<T> wrapper = null;

    /**
     * 不建议直接 new 该实例，使用 Wrappers.lambdaQuery(entity)
     */
    private EntityLambdaWrap() {
        super.initNeed();
    }

    public EntityLambdaWrap(Class<T> entityClass) {
        this();
        this.entityClass = entityClass;
        this.wrapper = new EntityWrap<>(entityClass);
    }

    /**
     * 不建议直接 new 该实例，使用 Wrappers.lambdaQuery(...)
     */
    public EntityLambdaWrap(Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, EntityWrap<T> wrapper) {
        this.paramNameValuePairs = paramNameValuePairs;
        this.expression = mergeSegments;
        this.wrapper = wrapper;
        this.entityClass = wrapper.getEntityClass();
    }

    @Override
    protected EntityLambdaWrap<T> instance() {
        return new EntityLambdaWrap<>(paramNameValuePairs, new MergeSegments(), this.wrapper);
    }

    @Override
    public EntityLambdaWrap<T> selectAll(Class<?> clazz) {
        String selectAllColumn = TableHelperUtil.getSelectAllColumnNoTable(clazz);
        return doIt(SqlKeyword.SELECT, selectAllColumn);
    }

    @Override
    public String columnToString(SFunction<T, ?> column) {
        String fieldName = LambdaUtils.getFieldProperty(column);
        Class<T> clazz = LambdaUtils.getFuncClass(column);
        String colunmString = TableHelperUtil.getEntityFieldColumn(clazz, fieldName);
        return colunmString;
    }

    /**
     * 选取一列
     */
    @Override
    public String selectToString(SFunction<T, ?> column) {
        String fieldName = LambdaUtils.getFieldProperty(column);
        Class<?> clazz = LambdaUtils.getFuncClass(column);
        String colunmString = TableHelperUtil.getEntityFieldColumn(clazz, fieldName);
        return colunmString + SQLKeyUtils.asFieldColumn(fieldName, colunmString);
    }

    /**
     * 选取多列
     *
     * @param columns
     * @return
     */
    @Override
    public String selectsToString(SFunction<T, ?>... columns) {
        return Arrays.stream(columns).map(this::selectToString).collect(joining(StringPool.COMMA));
    }

    public EntityWrap<T> getWrapper() {
        return this.wrapper;
    }

}